/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.wlhy.report;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.third.amap.service.HyShippingNoteAmapService;
import org.jeecg.modules.third.daikai.daoda.DaodaService;
import org.jeecg.modules.third.daikai.daoda.dto.AddOrderDTO;
import org.jeecg.modules.third.daikai.daoda.dto.OrderLineDTO;
import org.jeecg.modules.third.daikai.daoda.dto.OrderLineObjDTO;
import org.jeecg.modules.third.amap.dto.GpsDTO;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.hyarea.entity.HyArea;
import org.jeecg.modules.wlhy.hyarea.service.IHyAreaService;
import org.jeecg.modules.wlhy.hydaodaorder.entity.HyDaodaOrder;
import org.jeecg.modules.wlhy.hydaodaorder.service.IHyDaodaOrderService;
import org.jeecg.modules.wlhy.hydaodauser.entity.HyDaodaUser;
import org.jeecg.modules.wlhy.hydaodauser.service.IHyDaodaUserService;
import org.jeecg.modules.wlhy.hydaodavehicle.entity.HyDaodaVehicle;
import org.jeecg.modules.wlhy.hydaodavehicle.service.IHyDaodaVehicleService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.impl.HyVehicleServiceImpl;
import org.jeecg.modules.wlhy.order.entity.HyOrder;
import org.jeecg.modules.wlhy.order.service.impl.HyOrderServiceImpl;
import org.jeecg.modules.wlhy.shipping.entity.DaodaUpDataShippingNoteDTO;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.PointDataListVO;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.shipping.mapper.HyShippingNoteMapper;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 道达模块
 *
 * @author duanlikao
 * @created 2022/3/23
 */
@Service
public class ShippingNoteDaodaService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShippingNoteDaodaService.class);

    @Resource
    private HyShippingNoteMapper hyShippingNoteMapper;

    @Autowired
    private IHyShippingNoteService hyShippingNoteService;

    @Autowired
    private HyVehicleServiceImpl vehicleService;

    @Autowired
    private DaodaService daodaService;

    @Autowired
    private IHyDaodaUserService hyDaodaUserService;

    @Autowired
    private IHyDaodaOrderService hyDaodaOrderService;

    @Autowired
    private IHyDaodaVehicleService hyDaodaVehicleService;

    @Autowired
    private SysBaseApiImpl sysBaseApiImpl;

    @Autowired
    private IHyAreaService hyAreaService;

    @Autowired
    private HyOrderServiceImpl orderService;

    @Autowired
    private HyShippingNoteAmapService shippingNoteAmapService;

    @Autowired
    private IHyShippingNoteBillService hyShippingNoteBillService;

    @Autowired
    private WaybillRouteService waybillRouteService;


    /**
     *
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage<DaodaUpDataShippingNoteDTO> getDaodaUpDataPageList(Page<DaodaUpDataShippingNoteDTO> page,
            QueryWrapper<DaodaUpDataShippingNoteDTO> queryWrapper) {
        IPage<DaodaUpDataShippingNoteDTO> pageList = hyShippingNoteMapper.getDaodaUpDataPageList(page, queryWrapper);
        return pageList;
    }


    /**
     * 道达运单上报
     *
     * @param hyShippingNote
     * @return
     */

    @Transactional(rollbackFor = Exception.class)
    public boolean uploadDaoda(HyShippingNote hyShippingNote) {
        HyShippingNote hyShippingNoteDb = hyShippingNoteService.getById(hyShippingNote.getId());
        if (hyShippingNoteDb == null) {
            throw new JeecgBootException("未找到对应数据");
        }
        if (hyShippingNoteDb.getDaodaUploadStatus().equals("1")) {
            throw new JeecgBootException("该数据已上报过，请勿重复上报！");
        }

        LambdaQueryWrapper<HyDaodaUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HyDaodaUser::getDriverId, hyShippingNoteDb.getDriverId());
        HyDaodaUser daodaUser = hyDaodaUserService.getOne(queryWrapper);
        if (daodaUser == null) {
            throw new JeecgBootException("该司机没上报道达，请先上报该司机！");
        }

        LambdaQueryWrapper<HyDaodaVehicle> queryWrapperDaodaVehicle = new LambdaQueryWrapper<>();
        queryWrapperDaodaVehicle.eq(HyDaodaVehicle::getVehicleId, hyShippingNoteDb.getVehicleId());
        queryWrapperDaodaVehicle.eq(HyDaodaVehicle::getDriverId, hyShippingNoteDb.getDriverId());
        HyDaodaVehicle daodaVehicl = hyDaodaVehicleService.getOne(queryWrapperDaodaVehicle);
        if (daodaVehicl == null) {
            vehicleService.uploadDaoda(
                    new HyVehicle()
                            .setId(hyShippingNoteDb.getVehicleId())
                            .setDriverId(hyShippingNoteDb.getDriverId())
            );
            //              throw new JeecgBootException("该车辆没上报道达，请先上报该车辆！");
        }

        //HyOrder hyOrder = orderService.getById(hyShippingNoteDb.getOrderId());
        //if (hyOrder == null) {
        //    throw new JeecgBootException("该运单货源信息不存在！");
        //}

        AddOrderDTO addOrderDTO = getAddOrderDTO(hyShippingNote, daodaUser);

        String reportResult = daodaService.addOrder(addOrderDTO);
        if (StringUtils.isNotEmpty(reportResult)) {
            JSONObject jsonObject = JSONObject.parseObject(reportResult);
            boolean success = jsonObject.getBoolean("success") != null ? jsonObject.getBoolean("success") : false;
            String resultMsg = jsonObject.getString("ResultMsg") != null  ? jsonObject.getString("ResultMsg") :StringUtils.EMPTY;

            hyShippingNoteDb.setDaodaUploadStatus(success ? "1" : "2");
            hyShippingNoteDb.setDaodaUploadTime(new Date());
            hyShippingNoteDb.setDaodaFailureReason(resultMsg);
            hyShippingNoteService.updateById(hyShippingNoteDb);
            if (!success) {
                throw new JeecgBootException(resultMsg);
            }
            LambdaQueryWrapper<HyDaodaOrder> queryWrapperDaodaOrder = new LambdaQueryWrapper<>();
            queryWrapperDaodaOrder.eq(HyDaodaOrder::getShippingnoteId, hyShippingNoteDb.getId());
            HyDaodaOrder daodaOrder = hyDaodaOrderService.getOne(queryWrapperDaodaOrder);

            HyDaodaOrder hyDaodaOrder = new HyDaodaOrder();
            hyDaodaOrder.setShippingnoteId(hyShippingNoteDb.getId());
            hyDaodaOrder.setShippingNoteNumber(hyShippingNoteDb.getShippingNoteNumber());
            String orderKey = jsonObject.getString("OrderKey");
            hyDaodaOrder.setOrderId(orderKey);

            if (daodaOrder != null) {
                hyDaodaOrder.setId(daodaOrder.getId());
                return hyDaodaOrderService.updateById(hyDaodaOrder);
            } else {
                hyDaodaOrder.setCreateTime(new Date());
                return hyDaodaOrderService.save(hyDaodaOrder);
            }
        }

        return false;
    }

    /**
     * 推送道达运单轨迹
     *
     * @param hyShippingNote
     * @return
     */
    public boolean uploadDaodaOrderLine(HyShippingNote hyShippingNote) {
        HyShippingNote hyShippingNoteDb = hyShippingNoteService.getById(hyShippingNote.getId());
        if (hyShippingNoteDb == null) {
            throw new JeecgBootException("未找到对应数据");
        }

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNoteDb.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单无车辆信息！");
        }

        LambdaQueryWrapper<HyDaodaOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HyDaodaOrder::getShippingnoteId, hyShippingNoteDb.getId());
        HyDaodaOrder daodaOrder = hyDaodaOrderService.getOne(queryWrapper);
        if (daodaOrder == null) {
            throw new JeecgBootException("该运单未推送，请先推送该运单！");
        }
        if ("1".equals(daodaOrder.getUploadStatus())) {
            throw new JeecgBootException("该运单轨迹已推送，请勿重复推送！");
        }

        OrderLineDTO orderLineDTO = new OrderLineDTO();
        orderLineDTO.setOrderKey(daodaOrder.getOrderId());

        List <OrderLineObjDTO> orderLineObjDTOS = getOrderLineObjDTOS(hyVehicle, hyShippingNoteDb);
        if (CollectionUtils.isEmpty(orderLineObjDTOS)) {
            HyOrder hyOrder = orderService.getById(hyShippingNoteDb.getOrderId());
            if (hyOrder == null) {
                throw new JeecgBootException("该运单货源信息不存在！");
            }
            List<GpsDTO> gpsDTOs = shippingNoteAmapService.getMapGps(hyShippingNoteDb);

            if (CollectionUtils.isNotEmpty(gpsDTOs)) {
                int a = gpsDTOs.size();
                if (a <= 1000) {
                    for (GpsDTO pointDataListVO : gpsDTOs) {
                        OrderLineObjDTO gpsDTO = new OrderLineObjDTO();
                        gpsDTO.setPositionX(pointDataListVO.getLon());
                        gpsDTO.setPositionY(pointDataListVO.getLat());
                        gpsDTO.setStrLocation(pointDataListVO.getLon() + "," + pointDataListVO.getLat());
                        gpsDTO.setAddtime(pointDataListVO.getPositionTime());
                        orderLineObjDTOS.add(gpsDTO);
                    }
                } else {
                    int b = getFrequency(a);
                    int n = 1;
                    for (GpsDTO pointDataListVO : gpsDTOs) {
                        if (n % b == 0) {
                            OrderLineObjDTO gpsDTO = new OrderLineObjDTO();
                            gpsDTO.setPositionX(pointDataListVO.getLon());
                            gpsDTO.setPositionY(pointDataListVO.getLat());
                            gpsDTO.setStrLocation(pointDataListVO.getLon() + "," + pointDataListVO.getLat());
                            gpsDTO.setAddtime(pointDataListVO.getPositionTime());
                            orderLineObjDTOS.add(gpsDTO);
                        }
                        n++;
                    }
                }

            }
        }

        if (CollectionUtils.isEmpty(orderLineObjDTOS)) {
            throw new JeecgBootException("该运单无行车轨迹！");
        }

        orderLineDTO.setOrderLineObj(JSONObject.toJSONString(orderLineObjDTOS));

        String reportResult = daodaService.orderLine(orderLineDTO);
        if (StringUtils.isNotEmpty(reportResult)) {
            JSONObject jsonObject = JSONObject.parseObject(reportResult);
            boolean success = jsonObject.getBoolean("success") != null ? jsonObject.getBoolean("success") : false;
            String resultMsg = jsonObject.getString("ResultMsg") != null  ? jsonObject.getString("ResultMsg") :StringUtils.EMPTY;

            daodaOrder.setUploadStatus(success ? "1" : "2");
            daodaOrder.setUploadTime(new Date());
            daodaOrder.setFailureReason(resultMsg);
            hyDaodaOrderService.updateById(daodaOrder);
            if (!success) {
                throw new JeecgBootException(resultMsg);
            }
            return success ;
        }
        return false;
    }

    /**
     * 道达运单轨迹
     *
     * @param hyVehicle
     * @param hyShippingNote
     * @return
     */
    private List<OrderLineObjDTO> getOrderLineObjDTOS(HyVehicle hyVehicle, HyShippingNote hyShippingNote) {
        List<OrderLineObjDTO> gpsDTOS = new ArrayList <>();
        String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtReceive());
        String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
        String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
        WaybillRouteVO waybillRouteVO = waybillRouteService.getWaybillRoute(hyVehicle.getVehicleNumber(), vehicleColor,  startTime, endTime, "GCJ02");
        if (waybillRouteVO != null && CollectionUtils.isNotEmpty(waybillRouteVO.getPointDataList())) {
            List<PointDataListVO> pointDataListVOS = waybillRouteVO.getPointDataList();
            int a = pointDataListVOS.size();

            if (a <= 1000) {
                for (PointDataListVO pointDataListVO : pointDataListVOS) {
                    OrderLineObjDTO gpsDTO = new OrderLineObjDTO();
                    gpsDTO.setPositionX(pointDataListVO.getLng());
                    gpsDTO.setPositionY(pointDataListVO.getLat());
                    gpsDTO.setStrLocation(pointDataListVO.getLng() + "," + pointDataListVO.getLat());
                    gpsDTO.setAddtime(pointDataListVO.getReceiveTime());
                    gpsDTOS.add(gpsDTO);
                }
            } else {
                int b = getFrequency(a);
                int n = 1;
                for (PointDataListVO pointDataListVO : pointDataListVOS) {
                    if (n % b == 0) {
                        OrderLineObjDTO gpsDTO = new OrderLineObjDTO();
                        gpsDTO.setPositionX(pointDataListVO.getLng());
                        gpsDTO.setPositionY(pointDataListVO.getLat());
                        gpsDTO.setStrLocation(pointDataListVO.getLng() + "," + pointDataListVO.getLat());
                        gpsDTO.setAddtime(pointDataListVO.getReceiveTime());
                        gpsDTOS.add(gpsDTO);
                    }
                    n++;
                }
            }

        }
        return gpsDTOS;
    }

    /**
     * 道达运单组装数据
     *
     * @param hyShippingNote
     * @param daodaUser
     * @return
     */
    private AddOrderDTO getAddOrderDTO(HyShippingNote hyShippingNote, HyDaodaUser daodaUser) {

        LambdaQueryWrapper<HyShippingNoteBill> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HyShippingNoteBill::getShippingId, hyShippingNote.getId());
        List<HyShippingNoteBill> hyShippingNoteBills = hyShippingNoteBillService.list(queryWrapper);
        if (hyShippingNoteBills.isEmpty()) {
            throw new JeecgBootException("该运单流水单信息不存在！");
        }
        List<String> bankHdImgs = new ArrayList<>();
        for(HyShippingNoteBill hyShippingNoteBill:hyShippingNoteBills){
            String bankHdImg = "1".equals(hyShippingNoteBill.getPayChannel()) ? hyShippingNoteBill.getBankHd() : hyShippingNoteBill.getBankHdImg();

            if (StringUtils.isEmpty(bankHdImg)) {
                hyShippingNote.setDaodaUploadStatus("2");
                hyShippingNote.setDaodaUploadTime(new Date());
                hyShippingNote.setDaodaFailureReason("该运单银行回单信息不存在！");
                hyShippingNoteService.updateById(hyShippingNote);
                throw new JeecgBootException("该运单银行回单信息不存在！");
            }
            bankHdImgs.add(
                    daodaService.uploadFiles(bankHdImg)
            );
        }


        AddOrderDTO addOrderDTO = new AddOrderDTO();
        addOrderDTO.setMOrderNum(hyShippingNote.getShippingNoteNumber());
        addOrderDTO.setDriverID(daodaUser.getUserId());

        HyArea sendAreaCode = getAreaNames(hyShippingNote.getSendAreaCode() + "000000");
        if (sendAreaCode == null) {
            hyShippingNote.setDaodaUploadStatus("2");
            hyShippingNote.setDaodaUploadTime(new Date());
            hyShippingNote.setDaodaFailureReason("发货区域行政编码不存在！");
            hyShippingNoteService.updateById(hyShippingNote);
            throw new JeecgBootException("发货区域行政编码不存在！");
        }

        List<String> sendNames = Arrays.asList(sendAreaCode.getMergerName().split(","));
        addOrderDTO.setSProvince(sendNames.get(0));
        addOrderDTO.setSCity(sendNames.get(1));
        addOrderDTO.setSCounty(sendAreaCode.getName());

        HyArea receiveAreaCode = getAreaNames(hyShippingNote.getReceiveAreaCode() + "000000");
        if (receiveAreaCode == null) {
            hyShippingNote.setDaodaUploadStatus("2");
            hyShippingNote.setDaodaUploadTime(new Date());
            hyShippingNote.setDaodaFailureReason("收货区域行政编码不存在！");
            hyShippingNoteService.updateById(hyShippingNote);
            throw new JeecgBootException("收货区域行政编码不存在！");
        }
        List<String> receivNames = Arrays.asList(receiveAreaCode.getMergerName().split(","));
        addOrderDTO.setEProvince(receivNames.get(0));
        addOrderDTO.setECity(receivNames.get(1));
        addOrderDTO.setECounty(receiveAreaCode.getName());

        addOrderDTO.setStartAddress(hyShippingNote.getSendAddress());
        addOrderDTO.setEndAddress(hyShippingNote.getReceiveAddress());

        String className = sysBaseApiImpl.translateDict("cargo_type_classification_code", hyShippingNote.getCargoTypeClassificationCode());
        addOrderDTO.setClassName(className);
        addOrderDTO.setShippername(hyShippingNote.getDescriptionOfGoods());
        addOrderDTO.setStrWeight(hyShippingNote.getGoodsWeightLoading().toString());
        addOrderDTO.setStrVolume("0");
        addOrderDTO.setStartDate(DateUtils.dateTimeToString(hyShippingNote.getStatusDtLoading()));
        addOrderDTO.setEndDate(DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading()));
        addOrderDTO.setRecieveName(hyShippingNote.getReceiveContactName());
        addOrderDTO.setRecieveMobile(hyShippingNote.getReceiveContactTel());

        BigDecimal costPayShipping = hyShippingNote.getDriverFee() ;

        addOrderDTO.setOrderAmount( costPayShipping.toString());
        addOrderDTO.setAddtime(DateUtils.dateTimeToString(hyShippingNote.getStatusDtReceive()));

        addOrderDTO.setLoaddate(DateUtils.dateTimeToString(hyShippingNote.getStatusDtReceive()));

        addOrderDTO.setServeddate(DateUtils.dateTimeToString(hyShippingNote.getStatusDtSign()));
        addOrderDTO.setDefraydate(DateUtils.dateTimeToString(hyShippingNote.getPayDt()));
        addOrderDTO.setLastdate(DateUtils.dateTimeToString(hyShippingNote.getPayDt()));
        //String str = String.join(",", bankHdImgs);
        addOrderDTO.setReceiptInfo(bankHdImgs.stream().collect(Collectors.joining(",")));
        return addOrderDTO;
    }

    private HyArea getAreaNames(String areaCode) {
        LambdaQueryWrapper<HyArea> queryWrapperArea = new LambdaQueryWrapper <>();
        queryWrapperArea.eq(HyArea::getAreaCode, areaCode);
        return hyAreaService.getOne(queryWrapperArea);
    }

    /**
     * 获取频次
     *
     * @param a
     * @return
     */
    private int getFrequency(Integer a) {
        int b = 1;
        if (a > 1000 && a <= 2000) {
            b = 10;
        } else if (a > 2000 && a <= 3000) {
            b = 20;
        } else if (a > 3000 && a <= 4000) {
            b = 30;
        } else if (a > 4000 && a <= 5000) {
            b = 40;
        } else if (a > 5000 && a <= 6000) {
            b = 50;
        } else {
            b = 60;
        }
        return b;
    }

}
